import time
from flask import request, g, current_app
from .request import RequestLogger
from enums import HttpStatus


def identify_exception_type(exception):
    """
    识别异常类型，返回错误类型和HTTP状态码
    
    Args:
        exception: 异常对象
        
    Returns:
        tuple: (error_type, status_code)
    """
    exception_name = exception.__class__.__name__
    exception_str = str(exception).lower()
    
    # 数据库相关异常
    if any(keyword in exception_name.lower() for keyword in ['operational', 'database', 'connection', 'sql']):
        if 'timeout' in exception_str or 'timed out' in exception_str:
            return "数据库超时", HttpStatus.GATEWAY_TIMEOUT
        elif 'connection' in exception_str:
            return "数据库连接失败", HttpStatus.SERVICE_UNAVAILABLE
        else:
            return "数据库错误", HttpStatus.INTERNAL_SERVER_ERROR
    
    # Redis相关异常
    elif any(keyword in exception_name.lower() for keyword in ['redis', 'connection']):
        if 'timeout' in exception_str:
            return "Redis超时", HttpStatus.GATEWAY_TIMEOUT
        else:
            return "Redis连接失败", HttpStatus.SERVICE_UNAVAILABLE
    
    # 网络请求异常
    elif any(keyword in exception_name.lower() for keyword in ['requests', 'urllib', 'http']):
        if 'timeout' in exception_str:
            return "外部API超时", HttpStatus.GATEWAY_TIMEOUT
        else:
            return "外部API错误", HttpStatus.BAD_GATEWAY
    
    # 内存异常
    elif 'memory' in exception_name.lower():
        return "内存不足", HttpStatus.INSUFFICIENT_STORAGE
    
    # 文件操作异常
    elif any(keyword in exception_name.lower() for keyword in ['file', 'io', 'permission']):
        return "文件操作失败", HttpStatus.INTERNAL_SERVER_ERROR
    
    # HTTP相关异常
    elif hasattr(exception, 'code') and exception.code:
        try:
            status = HttpStatus.get_by_code(exception.code)
            return f"HTTP错误({status.description})", status
        except ValueError:
            return f"HTTP错误({exception.code})", HttpStatus.INTERNAL_SERVER_ERROR
    
    # 超时相关异常
    elif 'timeout' in exception_str or 'timed out' in exception_str:
        return "操作超时", HttpStatus.REQUEST_TIMEOUT
    
    # 默认异常
    else:
        return f"服务器内部错误({exception_name})", HttpStatus.INTERNAL_SERVER_ERROR


def setup_simple_request_hooks(app):
    """
    设置简化统一的全局请求钩子
    - 记录所有完整的HTTP请求和响应信息
    - 捕获所有Flask内部异常（数据库、Redis、API等）
    - 不设置应用层超时（交给具体服务控制）
    - 不限制headers大小（记录完整信息）
    
    Args:
        app: Flask应用实例
    """
    
    @app.before_request
    def before_request():
        """请求开始前的钩子"""
        g.start_time = time.time()
        g.request_logger = RequestLogger()  # 使用默认配置，记录完整信息
        
        # 调试模式下输出到控制台
        if current_app.debug:
            print(f"🌐 Request: {request.method} {request.path}")
    
    @app.after_request
    def after_request(response):
        """请求结束后的钩子 - 记录成功的请求"""
        if hasattr(g, 'start_time') and hasattr(g, 'request_logger'):
            try:
                # 计算响应时间
                response_time = int((time.time() - g.start_time) * 1000)
                
                # 判断请求状态
                method = request.method
                path = request.path
                try:
                    status_code = HttpStatus.get_by_code(response.status_code)
                except ValueError:
                    status_code = HttpStatus.INTERNAL_SERVER_ERROR
                
                # 构建日志消息
                if response_time > 1000:
                    message = f"性能警告: {request.endpoint or 'unknown'} 响应时间 {response_time}ms 超过阈值"
                elif status_code.is_success:
                    message = f"请求成功: {method} {path}"
                else:
                    # 所有错误（包括客户端错误和服务器错误）都记录为ERROR级别
                    if status_code.is_client_error:
                        message = f"客户端错误: {method} {path} ({status_code.description})"
                    else:
                        message = f"服务器错误: {method} {path} ({status_code.description})"
                
                # 记录完整的请求和响应信息
                g.request_logger.log_request_complete(
                    message=message,
                    request_obj=request,
                    response_obj=response,
                    response_time=response_time
                )
            except Exception as e:
                g.request_logger.error(f"日志记录失败: {str(e)}")
        
        return response
    
    # @app.teardown_request
    # def teardown_request(exception=None):
    #     """请求清理钩子 - 捕获所有Flask内部异常"""
    #     if exception and hasattr(g, 'request_logger'):
    #         try:
    #             if hasattr(g, 'start_time'):
    #                 response_time = int((time.time() - g.start_time) * 1000)
    #             else:
    #                 response_time = None
    #
    #             # 智能识别异常类型
    #             error_type, status_code = identify_exception_type(exception)
    #
    #             # 构建错误消息
    #             if status_code.is_client_error:
    #                 message = f"客户端错误: {request.method} {request.path} ({status_code.description})"
    #             else:
    #                 message = f"服务器错误: {request.method} {request.path} ({status_code.description})"
    #
    #             # 构建模拟的响应对象（用于记录错误信息）
    #             class ErrorResponse:
    #                 def __init__(self, status_code, error_type, error_msg):
    #                     self.status_code = status_code.code
    #                     self.headers = {
    #                         'content-type': 'application/json'
    #                     }
    #                     self.mimetype = 'application/json'
    #                     self._error = {
    #                         'error_type': error_type,
    #                         'error_message': str(error_msg)
    #                     }
    #
    #             error_response = ErrorResponse(status_code, error_type, exception)
    #
    #             # 记录完整的请求和错误信息
    #             g.request_logger.log_request_complete(
    #                 message=message,
    #                 request_obj=request,
    #                 response_obj=error_response,
    #                 response_time=response_time
    #             )
    #         except Exception as log_error:
    #             g.request_logger.error(f"异常日志记录失败: {str(log_error)}")